<template>
  <ie-page :loading="loading">

    <template #extra>
      <n-space>
        <n-popconfirm :on-positive-click="back">
          <template #trigger>
            <n-button>取消</n-button>
          </template>
          是否取消，当前编写内容不会被保存？
        </n-popconfirm>
        <template v-if="isEditing">
          <n-button @click="handleReset">撤销修改</n-button>
          <n-divider vertical style="height: 34px;" />
        </template>
        <n-button @click="handleConfirm" type="primary">保存</n-button>
      </n-space>
    </template>

    <div class="ie-form">
      <a-form
        :model="formValue"
        :style="{ width: '640px', margin: '0 auto 36px' }"
        :rules="formRules"
        @submit="handleSubmit"
        layout="vertical"
        size="large"
        ref="formRef"
      >
        <!-- disable chrome autocomplete -->
        <input name="password" type="password" style="display:none" autocomplete="new-password" />

        <template v-if="!isEditing">
          <a-form-item field="username" label="用户账号">
            <a-input v-model="formValue.username" placeholder="请输入用户账号..." />
          </a-form-item>
          <a-form-item field="password" label="用户密码">
            <a-input-password v-model="formValue.password" placeholder="请输入用户密码..." allow-clear />
          </a-form-item>
        </template>

        <a-form-item field="nickname" label="用户昵称">
          <a-input v-model="formValue.nickname" placeholder="请输入用户昵称..." />
        </a-form-item>
        <a-form-item field="phone" label="联系电话">
          <a-input-number v-model="formValue.phone" placeholder="请输入联系电话..." />
        </a-form-item>
        <a-form-item field="department_id" label="所属部门">
          <a-tree-select
            :allow-search="true"
            :allow-clear="true"
            :data="departmentOptions"
            :filter-tree-node="filterDepartment"
            v-model="formValue.department_id"
            placeholder="请选择所属部门..."
          ></a-tree-select>
        </a-form-item>

        <a-row :gutter="16">
          <a-col :span="12">
            <a-form-item field="role_id" label="用户角色">
              <a-select
                v-model="formValue.role_id"
                placeholder="请选择用户角色..."
                allow-clear
              >
                <a-option
                  v-for="option in roleOptions"
                  :value="option.id"
                  :key="option.id"
                >{{ option.name }}</a-option>
              </a-select>
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item
              v-if="showDistrict"
              field="district_id"
              label="负责辖区"
            >
              <a-select
                v-model="formValue.district_id"
                placeholder="请选择负责辖区..."
                :max-tag-count="2"
                :style="{ whiteSpace: 'nowrap' }"
                multiple
                allow-clear
              >
                <a-option
                  v-for="option in districtOptions"
                  :value="option.id"
                  :key="option.id"
                >{{ option.name }}</a-option>
              </a-select>
            </a-form-item>
          </a-col>
        </a-row>

      </a-form>
    </div>

    <!-- <ie-form
      :model="SystemUserModel"
      :passby="passby"
      ref="formRef"
    /> -->
  </ie-page>
</template>

<script setup>
import { computed, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useNotification } from 'naive-ui'
import { cloneDeep, isEmpty, isNil, isNaN, omit } from 'lodash-es'
import { useQuery } from 'villus'
import gql from 'graphql-tag'

import { useApi } from '/@/api'
import { useGraphqlClient } from '/@/graphql'

import { makeUpTree } from '/@/utils/helper'

const formRef = ref()
const loading = ref(false)

const route = useRoute()
const router = useRouter()
const notify = useNotification()

const isEditing = !isEmpty(route.params)

const formInitValue = {
  username: null,
  password: null,
  nickname: null,
  phone: null,
  role_id: '',
  department_id: '',
  district_id: []
}
const formValue = ref(cloneDeep(formInitValue))
const formRules = {
  username: [
    { required: true, message: '用户账号不可为空' },
    { minLength: 6, maxLength: 20, message: '用户账号长度为 6-20 位' },
    { match: /^[0-9a-zA-Z-_]+$/, message: '用户账号仅可为数字、字母、上下划线' }
  ],
  password: [
    { required: true, message: '用户密码不可为空' },
    { minLength: 6, maxLength: 20, message: '用户密码长度为 6-20 位' },
    { match: /^[0-9a-zA-Z-_@!+]+$/, message: '用户密码仅可为数字、字母、-_@!+' }
  ],
  nickname: [
    { required: true, message: '用户昵称不可为空' },
    { match: /^[^\s]+$/, message: '用户昵称不可包含空格' }
  ],
  department_id: [
    { required: true, message: '所属部门为必填项' }
  ],
  role_id: [
    { required: true, message: '角色为必填项' }
  ]
}

if (isEditing) {
  loading.value = true
  useGraphqlClient().executeQuery({
    query: gql`
      query ($id: uuid!) {
        ie_system_user_by_pk (id: $id) {
          nickname
          phone
          ie_system_user_role {
            id
          }
          system_user_meta {
            department_id
            system_users_districts {
              district_id
            }
          }
        }
      }
    `,
    variables: route.params
  }).then(res => {
    if (!res.error) {
      const data = res.data?.ie_system_user_by_pk

      if (!data) return back()

      const {
        ie_system_user_role,
        system_user_meta = {},
        phone,
        ...formProps
      } = data

      for (let key in formProps) {
        if (formInitValue[key] !== undefined) {
          formInitValue[key] = formProps[key]
        }
      }

      if (!isNaN(Number(phone))) {
        formInitValue.phone = Number(phone)
      }

      if (ie_system_user_role?.id) {
        formInitValue.role_id = ie_system_user_role.id
      }

      if (system_user_meta?.department_id) {
        formInitValue.department_id = system_user_meta.department_id
      }

      if (Array.isArray(system_user_meta?.system_users_districts)) {
        formInitValue.district_id = system_user_meta.system_users_districts.map(
          ({ district_id }) => district_id
        )
      }

      formValue.value = cloneDeep(formInitValue)
    }
    loading.value = false
  })
}

function handleConfirm() {
  if (formRef.value?.handleSubmit) {
    formRef.value?.handleSubmit()
  }
}

const { data } = useQuery({
  query: gql`
    query ($where: district_bool_exp) {
      ie_system_user_role {
        id
        role
        rolename
      }
      department {
        id
        name
        parent_id
      }
      district (where: $where) {
        id
        name
      },
    }
  `,
  variables: computed(() => {
    if (formValue.value.department_id) {
      return { where: {
        department_id: {
          _eq: formValue.value.department_id
        }}
      }
    }
    return { where: {
      department_id: {
        _eq: -1 // empty
      }}
    }
  })
})

watch(
  () => formValue.value?.department_id,
  department_id => {
    if (department_id !== formInitValue.department_id) {
      formValue.value.district_id = []
    }
  }
)

const roleOptions = computed(() => {
  const { ie_system_user_role } = data.value || {}

  if (Array.isArray(ie_system_user_role)) {
    return ie_system_user_role.map(({ id, role, rolename }) => ({
      id,
      name: rolename,
      role
    }))
  }

  return []
})

const showDistrict = computed(() => {
  const currentRole = roleOptions.value.find(role => role.id === formValue.value.role_id)

  return currentRole && currentRole.role === 'police'
})

const departmentOptions = computed(() => {
  const { department } = data.value || {}

  if (Array.isArray(department)) {
    return makeUpTree(department)
  }

  return []
})

const districtOptions = computed(() => {
  const { district } = data.value || {}

  if (Array.isArray(district)) {
    return district
  }

  return []
})

function filterDepartment(searchValue, nodeData) {
  return nodeData.title.toLowerCase().indexOf(searchValue.toLowerCase()) > -1
}

function handleSubmit({ values, errors }) {
  const valuesClone = cloneDeep(values)

  if (errors) return
  if (!isNil(valuesClone.phone)) {
    valuesClone.phone = String(valuesClone.phone)
  }

  const onOk = (resp, content = '成功') => {
    if (resp.code === 0) {
      notify.success({
        content,
        meta: '即将跳到列表页',
        duration: 5e3,
        onAfterEnter: back
      })
    }
  }

  if (isEditing) {
    return useApi()
      .post('system-user/update', {
        ...omit(valuesClone, ['username', 'password']),
        ...route.params
      }, { authorize: true })
      .then(res => onOk(res, '修改用户成功'))
  }

  useApi()
    .post('system-user/create', valuesClone, { authorize: true })
    .then(res => onOk(res, '新建用户成功'))
}

function back() {
  router.push({ name: 'SystemUser' })
}

function handleReset() {
  formValue.value = cloneDeep(formInitValue)
}
</script>